<?php

namespace app\api\library;

use app\common\model\Cart;
use app\common\model\mall\Goods;
use app\common\model\mall\GoodsSku;
use app\common\model\Store;
use think\Cache;

class CacheCart
{
    /* @var string $error 错误信息 */
    public $error = '';

    /* @var int $user_id 用户id */
    private $user_id;

    /* @var array $cart 购物车列表 */
    private $cart = [];

    /* @var bool $clear 是否清空购物车 */
    private $clear = false;

    /**
     * 构造方法
     * Cart constructor.
     * @param $user_id
     */
    public function __construct($user_id)
    {
        $this->user_id = $user_id;
        $this->cart = Cache::get('cart_' . $this->user_id) ?: [];
        if(empty($this->cart) ){
            $list = Cart::where('user_id',$user_id)->field('id,store_id,goods_id,goods_sku_id,goods_num,createtime')->select();
            if($list){
                foreach ($list as $k=>$v){
                    $index = $v['goods_id'] . '_' .$v['goods_sku_id'];
                    $this->cart[$index] = [
                        'store_id' => $v['store_id'],
                        'goods_id' => $v['goods_id'],
                        'goods_num' => $v['goods_num'],
                        'goods_sku_id' => $v['goods_sku_id'],
                        'createtime' => $v['createtime'],
                        'cart_id' => $v['id'],
                        'key' => $index,
                    ];
                }
            }
        }
    }

    private function skuInfo($goods_id)
    {
        $list = GoodsSku::where(['goods_id'=>['=',$goods_id]])->column('model,price,market_price,stock','id');
        return $list;
    }

    /**
     * 购物车列表
     */
    public function getList()
    {
        //店铺列表
        $storeList = [];
        $storeIds = array_unique(array_column($this->cart,'store_id'));
        // 商品总金额
        $orderTotalAmount = 0;
        foreach ((new Store())->where('id','in',$storeIds)->select() as $store) {
            //店铺正常
            if($store->state == '20'){
                //查找商品
                $goodsList = [];
                $goodsIds = Cart::where('user_id',$this->user_id)->where('store_id',$store->id)->field('goods_id,goods_sku_id,goods_num')->select();
                if($goodsIds){
                    foreach ($goodsIds as $key=>&$value){
                        // 商品信息
                        $goodsModel = new Goods();
                        $goods = $goodsModel->details($value['goods_id']);
                        // 判断商品不存在则自动删除
                        if(empty($goods)){
                            $this->delete($value['goods_id'], $value['goods_sku_id']);
                            continue;
                        }
                        //商品规格
                        $goodsSkuInfo = $this->skuInfo($value['goods_id']);
                        // 判断商品不存在则自动删除
                        if(empty($goodsSkuInfo)){
                            if (isset($goodsSkuInfo[$value['goods_sku_id']])) $this->delete($value['goods_id'], $value['goods_sku_id']);
                            continue;
                        }
                        $goodsSkuInfo = isset($goodsSkuInfo[$value['goods_sku_id']]) ? $goodsSkuInfo[$value['goods_sku_id']] : [];
                        // 商品sku信息   商品sku不存在则自动删除
                        if(empty($goodsSkuInfo)){
                            $this->delete($value['goods_id'], $value['goods_sku_id']);
                            continue;
                        }
                        $cart = $this->cart[$value['goods_id'] . '_' . $value['goods_sku_id']];
                        $temp = [
                            'goods_id' => $value['goods_id'],
                            'goods_sku_id' => $value['goods_sku_id'],
                            'goods_num' => $value['goods_num'],
                            'name' => $goods['name'],
                            'image' => $goods['image'],
                            'sku' => isset($goodsSkuInfo['model']) ? $goodsSkuInfo['model'] : '',
                            'price' => $goodsSkuInfo['price'],
                            'market_price' => isset($goodsSkuInfo['market_price']) ? $goodsSkuInfo['market_price'] : 0,
                            'show_error' => 0,
                            'key' => $value['goods_id'] . '_' . $value['goods_sku_id'],
                        ];
                        // 判断商品是否下架  state 商品状态:10=待审核,20=上架
                        if ($goods['state'] == '10') {
                            $temp['show_error'] = 1;
                            $temp['show_error_text'] = '已下架';
                            $this->setError('很抱歉，商品 [' . $goods['name'] . '] 已下架');
                        }
                        // 判断商品库存
                        if ($cart['goods_num'] > $goodsSkuInfo['stock']) {
                            $temp['show_error'] = 2;
                            $temp['show_error_text'] = '库存不足';
                            $this->setError('很抱歉，商品 [' . $goods['name'] . '] 库存不足');
                        }
                        // 商品总价
                        $temp['total_amount'] = $temp['show_error'] == 0 ? bcmul($temp['price'], $temp['goods_num'], 2) : 0;
                        $orderTotalAmount += $temp['total_amount'];
                        $goodsList[] = $temp;
                    }
                }
                if($goodsList){
                    $storeList[] = [
                        'store_id' => $store->id,
                        'name' => $store->shop_name,
                        'logo_image' => $store->logo_image_url,
                        'goodsList' => $goodsList,
                    ];
                }
            }
        }
        return [
            'list' => $storeList,                       // 商品列表
            'order_total_num' => $this->getTotalNum(),       // 商品总数量
            'order_total_amount' => round($orderTotalAmount, 2),              // 商品总金额 (不含运费)
        ];
    }

    /**
     * 添加购物车
     * @param $goods_id
     * @param $goods_sku_id
     * @param $goods_num
     * @return bool
     * @throws \think\exception\DbException
     */
    public function add($goods_id, $goods_sku_id,$goods_num)
    {
        // 商品信息
        $goodsModel = new Goods();
        $goods = $goodsModel->details($goods_id);
        if($goods === false){
            $this->setError($goodsModel->getError());
            return false;
        }
        $goods['sku'] = $this->skuInfo($goods_id);

        // 购物车商品索引
        $index = $goods_id . '_' . $goods_sku_id;
        if(!isset($goods['sku'][$goods_sku_id])){
            $this->setError(__('此规格不存在'));
            return false;
        }

        // 判断商品库存
        $cartGoodsNum = $goods_num + (isset($this->cart[$index]) ? $this->cart[$index]['goods_num'] : 0);
        if ($cartGoodsNum > $goods['sku'][$goods_sku_id]['stock']) {
            $this->setError(__('商品库存不足'));
            return false;
        }
        $createtime = time();
        $store_id = $goods['store_id'];
        //  compact 创建一个包含变量名和它们的值的数组
        $data = compact('goods_id', 'goods_num', 'goods_sku_id', 'createtime','store_id');
        if(empty($this->cart)  || ($this->cart && !isset($this->cart[$index]))){
            //添加到购物车
            $cartData =[
                'user_id' => $this->user_id,
                'store_id' => $store_id,
                'goods_id' => $goods_id,
                'goods_sku_id' => $goods_sku_id,
                'goods_num' => $cartGoodsNum,
            ];
            $cartModel = Cart::create($cartData);
            $data['cart_id'] = $cartModel->id;
        }
        if (empty($this->cart)) {
            $this->cart[$index] = $data;
            return true;
        }
        isset($this->cart[$index]) ? $this->cart[$index]['goods_num'] = $cartGoodsNum : $this->cart[$index] = $data;
        if($this->cart && isset($this->cart[$index]) && isset($this->cart[$index]['cart_id']) ){
            //改变购物车数量
            Cart::where('id',$this->cart[$index]['cart_id'])->update(['goods_num'=>$cartGoodsNum]);
        }
        return true;
    }

    /**
     * 减少购物车中某商品数量
     * @param $goods_id
     * @param $goods_sku_id
     */
    public function sub($goods_id, $goods_sku_id)
    {
        $index = $goods_id . '_' . $goods_sku_id;
        if(!isset($this->cart[$index])){
            $this->setError(__('Parameter error'));
            return false;
        }
        if($this->cart[$index]['goods_num'] == 1){
            $this->setError(__('不可减少'));
            return false;
        }
        $this->cart[$index]['goods_num']--;
        //改变购物车数量
        if(isset($this->cart[$index]) && isset($this->cart[$index]['cart_id'])){
            Cart::where('id',$this->cart[$index]['cart_id'])->setDec('goods_num');
        }
    }

    /**
     * 增加购物车中某商品数量
     * @param $goods_id
     * @param $goods_sku_id
     */
    public function inc($goods_id, $goods_sku_id)
    {
        $index = $goods_id . '_' . $goods_sku_id;
        if(!isset($this->cart[$index])){
            $this->setError(__('Parameter error'));
            return false;
        }
        $this->cart[$index]['goods_num']++;
        //改变购物车数量
        if(isset($this->cart[$index]) && isset($this->cart[$index]['cart_id'])){
            Cart::where('id',$this->cart[$index]['cart_id'])->setInc('goods_num');
        }
    }

    /**
     * 删除购物车中指定商品
     * @param $goods_id
     * @param $goods_sku_id
     */
    public function del($goods_id, $goods_sku_id)
    {
        $index = $goods_id . '_' . $goods_sku_id;
        if(!isset($this->cart[$index])){
            $this->setError(__('Parameter error'));
            return false;
        }
        //改变购物车数量
        if(isset($this->cart[$index]) && isset($this->cart[$index]['cart_id'])){
            Cart::where('id',$this->cart[$index]['cart_id'])->delete();
        }
        unset($this->cart[$index]);
        Cache::set('cart_' . $this->user_id, $this->cart, 86400 * 15);
    }

    /**
     * 获取当前用户购物车商品总数量
     * @return int
     */
    public function getTotalNum()
    {
        return array_sum(array_column($this->cart, 'goods_num'));
    }

    /**
     * 析构方法
     * 将cart数据保存到缓存文件
     */
    public function __destruct()
    {
        $this->clear !== true && Cache::set('cart_' . $this->user_id, $this->cart, 86400 * 15);
    }

    /**
     * 清空当前用户购物车
     */
    public function clearAll()
    {
        $this->clear = true;
        Cache::rm('cart_' . $this->user_id);
        Cart::where('user_id',$this->user_id)->delete();
    }

    /**
     * 设置错误信息
     * @param $error
     */
    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    /**
     * 是否存在错误
     * @return bool
     */
    private function hasError()
    {
        return !empty($this->error);
    }

    /**
     * 获取错误信息
     * @return string
     */
    public function getError()
    {
        return $this->error;
    }
}